package main

import "fmt"

func main() {
	// method1_2()
	// method2()
	fmt.Println(*method4())
}

func method1() {
	i := 0
	//method1结束时，输出的是0
	//是因为当defer被声明时，参数已经被解析了
	//而int又是值传递，因此实际上defer执行时，输出的是当时的值而非最后的值
	//method1_2 演示了如果是指针的话，就不一样了
	defer fmt.Println(i)
	i++
}

func method1_2() {
	i := 0
	//把int指针作为参数传递，等到执行时，再取值输出
	defer func(val *int) {
		fmt.Printf("defer时： %d\n", i)
	}(&i)
	i++
	fmt.Printf("defer之前： %d\n", i)
}

func method2() {
	i := 0
	//method1结束时，输出的是0
	//是因为当defer被声明时，参数已经被解析了
	defer fmt.Println(i)
	i++
	//输出1
	defer fmt.Println(i)
	//调用method2后，先输出1再输出0
	//defer的执行是FILO，先进后出
	//这是因为往往后面的变量可能依赖于之前的变量
	//如果按照声明顺序执行defer，则可能导致之后的defer执行失败

}

func method3() (i int) {
	//调用method3最终返回的值是2
	//因为i是实名返回值
	//return之前 i为1
	//return之后执行了defer中的i++，此时才真的返回i
	//也就是说，defer的执行还是在函数内的
	defer func() { i++ }()
	i++
	return
}

func method4() *int {
	i := 0
	defer func(num *int) { i++ }(&i)
	i++
	return &i
}
